﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using EzDesk.Core.Data;
using EzDesk.Core.Model;
using EzDesk.Core.Interface;
using EzDesk.Utility.Log;
using EzDesk.Utility;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreService : ICoreService
    {
        public CoreService()
        {
            //LogEx.TRACE("CoreService - CoreService", "初始化CoreService");
        }


        #region [ private methods ]

        private ICoreService self
        {
            get
            {
                return (ICoreService)this;
            }
        }


        private Guid[] convertSingleIdToIdCollection(Guid singleId)
        {
            Guid[] guids = new Guid[1]
            {
                singleId
            };
            return guids;
        }

        private Guid[] convertIdStrsToIdCollection(string idStrs)
        {
            var idStrList = idStrs.Split(',');

            List<Guid> idList = new List<Guid>();

            foreach (var idStr in idStrList)
            {
                Guid result;
                if (Guid.TryParse(idStr, out result))
                {
                    idList.Add(result);
                }
            }
            return idList.ToArray();
        }

        private void updateDeptGroupMemberstring()
        {
            EzDeskDatabaseContainer.Go(
                container =>
                {
                    // 先把所有dept找出来
                    var allDepts = container.DeptSet.ToList();
                    var allUsers = container.UserProfileSet.Select(
                        p => new
                                 {
                                     p.Id,
                                     p.DeptId,
                                 })
                        .ToList();
                    var allDeptGroups = container.GroupSet.Where(p => p.Type == 1).ToList();
                    foreach (var dept in allDepts)
                    {
                        var deptMemberstring = allUsers
                            .Where(p => p.DeptId == dept.Id)
                            .Select(p => p.Id).ToList().Join(",");

                        // 找相应的组，type = 1
                        var deptGroup = allDeptGroups.FirstOrDefault(p => p.Name == dept.Id.ToString());
                        if (deptGroup == null)
                        {
                            // 添加这个组
                            container.GroupSet.AddObject(
                                new Group()
                                {
                                    Id = Guid.NewGuid(),
                                    Description = dept.DeptName,
                                    Memberstring = deptMemberstring,
                                    Name = dept.Id.ToString(),
                                    Type = 1
                                });
                        }
                        else
                        {
                            // 更新memberstring
                            deptGroup.Memberstring = deptMemberstring;
                        }
                    }
                    container.SaveChanges();

                });
        }

        #endregion


        UserProfile ICoreService.GetUserProfileByUserName(string userName)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.UserProfileSet
                    .Include("Dept").Include("Position").FirstOrDefault(p => p.UserCode == userName));
        }

        UserProfile ICoreService.GetUserProfileById(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.UserProfileSet
                    .Include("Dept").Include("Position").FirstOrDefault(p => p.Id == userId));
        }

        UserProfile ICoreService.CreateEmptyUserProfile(string userName)
        {
            var userProfile =
                new UserProfile()
                    {
                        Id = Guid.NewGuid(),
                        UserCode = userName,
                    };
            EzDeskDatabaseContainer.GoAndSave(
                container => container.UserProfileSet.AddObject(userProfile));
            return userProfile;
        }

        void ICoreService.DeleteUserProfile(Guid userId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                    if (userProfile != null)
                    {
                        container.UserProfileSet.DeleteObject(userProfile);
                    }
                });
        }

        List<UserProfile> ICoreService.GetUserProfiles(Guid[] userIdCollection)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.UserProfileSet.Include("Dept").Include("Position")
                                 .Where(p => userIdCollection.Contains(p.Id)).ToList()
                );
        }


        List<UserProfile> ICoreService.GetUserProfiles(string memberstring)
        {
            Guid[] userIds = getAllUserIdsByMemberString(memberstring).ToArray();

            return self.GetUserProfiles(userIds);
        }

        SimpleUser ICoreService.GetSimpleUserById(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                {
                    var userProfile = container.UserProfileSet.Include("Dept").Include("Position").FirstOrDefault(p => p.Id == userId);
                    return userProfile.ToSimpleUser();
                });
        }




        List<SimpleUser> ICoreService.GetSimpleUserInfos(Guid[] userIdCollection)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                    {
                    var userProfiles = container.UserProfileSet.Include("Dept").Include("Position")
                        .Where(p => userIdCollection.Contains(p.Id)).ToList();
                        return userProfiles.ToSimpleUsers();
                });
        }

        List<SimpleUser> ICoreService.GetSimpleUserInfos(string memberstring)
        {
            Guid[] userIdsToSent = getAllUserIdsByMemberString(memberstring).ToArray();

            return self.GetSimpleUserInfos(userIdsToSent);
        }

        SimpleUser ICoreService.GetSimpleUserInfoByUserName(string userName)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                {
                    var userProfile = container.UserProfileSet.Include("Dept").Include("Position").FirstOrDefault(p => p.UserCode == userName);
                    SimpleUser simpleUser = null;
                    if (userProfile != null)
                    {
                        simpleUser = userProfile.ToSimpleUser();
                    }
                    return simpleUser;
                });
        }

        List<SimpleUser> ICoreService.GetUsersInDept(Guid deptId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                container.UserProfileSet.Include("Dept").Include("Position")
                    .Where(p => p.DeptId == deptId)
                    .ToList()
                    .Select(p => p.ToSimpleUser())
                    .ToList()
                );
        }

        List<Dept> ICoreService.GetAllDepts()
        {
            return EzDeskDatabaseContainer.Go(
                container => container.DeptSet.ToList());
        }

        List<Position> ICoreService.GetPositions()
        {
            return EzDeskDatabaseContainer.Go(
                container => container.PositionSet.ToList());
        }

        Dept ICoreService.GetDeptById(Guid deptId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.DeptSet.FirstOrDefault(p => p.Id == deptId)
                );

        }

        Dept ICoreService.CreateDept(string deptName)
        {
            return EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    //判断名字不重复
                    var dept = container.DeptSet.FirstOrDefault(p => p.DeptName == deptName);
                    if (dept != null)
                    {
                        throw new ApplicationException("部门名称重复了");
                    }

                    // 创建新的Dept 写入
                    var newDept = new Dept()
                                      {
                                          Id = Guid.NewGuid(),
                                          DeptName = deptName,
                                      };
                    var newGroup = new Group()
                                       {
                                           Id = Guid.NewGuid(),
                                           Description = deptName,
                                           Memberstring = "",
                                           Name = dept.Id.ToString(),
                                           Type = 1,
                                       };
                    container.DeptSet.AddObject(newDept);
                    container.GroupSet.AddObject(newGroup);

                    return newDept;
                });
        }
        void ICoreService.DeleteDept(Guid deptId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var dept = container.DeptSet.First(p => p.Id == deptId);
                    container.DeptSet.DeleteObject(dept);
                    var deptIdStr = deptId.ToString();
                    var deptGroup = container.GroupSet.FirstOrDefault(p => p.Name == deptIdStr);
                    if (deptGroup != null)
                    {
                        container.GroupSet.DeleteObject(deptGroup);
                    }
                    var users = container.UserProfileSet.Where(p => p.DeptId == deptId);
                    foreach (var userProfile in users)
                    {
                        userProfile.DeptId = null;
                    }
                });
        }

        List<SimpleUser> ICoreService.GetUsersInPosition(Guid posId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                container.UserProfileSet
                    .Include("Dept").Include("Position")
                    .Where(p => p.PositionId == posId)
                    .ToList()
                    .Select(p => p.ToSimpleUser())
                    .ToList()
                );
        }

        void ICoreService.ChangeDeptName(Guid deptId, string deptName)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var dept = container.DeptSet.FirstOrDefault(p => p.Id == deptId);
                    dept.DeptName = deptName;
                    var group = container.GroupSet.FirstOrDefault(p => p.Name == dept.Id.ToString());
                    group.Description = deptName;
                });
        }

        Position ICoreService.CreatePosition(string descrition, int priority)
        {
            var position =
                new Position()
                    {
                        Id = Guid.NewGuid(),
                        Description = descrition,
                        Priority = priority,
                    };
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    if (priority < 0)
                    {
                        priority = container.PositionSet.Max(p => p.Priority) + 1;
                    }
                    position.Priority = priority;
                    container.PositionSet.AddObject(position);
                });
            return position;
        }

        void ICoreService.ChangePositionPriority(Guid positionId, int priority)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    position.Priority = priority;
                });
        }

        void ICoreService.ChangePositionDescription(Guid positionId, string description)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    position.Description = description;
                });
        }

        void ICoreService.DeletePosition(Guid positionId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    container.PositionSet.DeleteObject(position);
                });
        }



        FeedTemplate ICoreService.CreateFeedTemplate(string titleTemplate, string bodyTemplate, int type)
        {
            throw new NotImplementedException();
        }

        void ICoreService.DeleteFeedTemplate(Guid id)
        {
            throw new NotImplementedException();
        }

        FeedTemplate ICoreService.GetFeedTemplateById(Guid templateId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.FeedTemplateSet.FirstOrDefault(p => p.Id == templateId));
        }

        List<FeedTemplate> ICoreService.GetFeedTemplate(string templateName)
        {
            // 如果没有传名字进来，那么直接返回所有的
            return EzDeskDatabaseContainer.Go(
                container =>
                {
                    IQueryable<FeedTemplate> query = container.FeedTemplateSet;
                    if (!string.IsNullOrEmpty(templateName))
                    {
                        query = query.Where(p => p.TemplateName == templateName);
                    }
                    return query.ToList();
                }
                );
        }





        public void UpdateHeadIcon(Guid userId, byte[] iconData, string imageType)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var userProfile = container.UserProfileSet.Include("UserHeadImage").FirstOrDefault(p => p.Id == userId);
                    if (userProfile.UserHeadImage != null)
                    {
                        container.UserHeadImageSet.DeleteObject(userProfile.UserHeadImage);
                        container.SaveChanges();
                    }
                    var newUserHeadImage =
                        new UserHeadImage()
                            {
                                Id = Guid.NewGuid(),
                                ImageData = iconData,
                                ImageType = imageType,
                                UpdateOn = DateTime.Now,
                            };
                    userProfile.UserHeadImage = newUserHeadImage;
                });
        }

        public UserHeadImage GetHeadIcon(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                {
                    var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                    container.LoadProperty(userProfile, p => p.UserHeadImage);
                    return userProfile.UserHeadImage;
                });
        }




        public void UpdateUserProfile(UserProfile userProfile)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    container.UserProfileSet.Attach(userProfile);
                    container.ObjectStateManager.ChangeObjectState(userProfile, EntityState.Modified);
                    updateDeptGroupMemberstring();
                });
        }





        public List<SimpleUser> GetAllUsers()
        {
            return EzDeskDatabaseContainer.GoAndSave(
                container => container.UserProfileSet.Include("Dept").Include("Position").ToList()
                                 .Select(userProfile => userProfile.ToSimpleUser())
                                 .ToList());
        }


        public void UpdateOrganizationInfo(Organization org)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var organization = container.OrganizationSet.FirstOrDefault(p => p.Id == org.Id);
                    organization.FullName = org.FullName;
                    organization.ShortName = org.ShortName;
                });
        }


        public List<Group> GetPermissionGroups()
        {
            return EzDeskDatabaseContainer.Go(
                container => container.GroupSet.Where(p => p.Type == 2).ToList());
        }


        public List<Group> GetUserPermissionGroups(Guid userId)
        {
            return GetUserInGroups(userId, 2);
        }


        public void RemovePosition(Guid positionId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    container.PositionSet.DeleteObject(position);
                });
        }

        public void SaveDeviceToken(Guid userId, string deviceToken)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {   
                        //删除已经存在的 设备 token
                        var tokenForTheDevice =
                            container.MobileDeviceTokenSet.FirstOrDefault(p => p.Device_Token == deviceToken);
                        if (tokenForTheDevice != null)
                            container.MobileDeviceTokenSet.DeleteObject(tokenForTheDevice);

                        //删除已经存在的 用户 token
                        var tokenForTheUser = container.MobileDeviceTokenSet.FirstOrDefault(p => p.UserId == userId);
                        if (tokenForTheUser != null)
                            container.MobileDeviceTokenSet.DeleteObject(tokenForTheUser);

                        //保存新的 token
                        var newDeviceToken = new MobileDeviceToken()
                                                 {
                                                     Id = Guid.NewGuid(),
                                                     UserId = userId,
                                                     Device_Token = deviceToken
                                                 };
                        container.MobileDeviceTokenSet.AddObject(newDeviceToken);
                    });

        }

        public string GetDeviceToken(Guid userId)
        {
            var deviceToken = "";
            EzDeskDatabaseContainer.GoAndSave(
                  container =>
                  {
                      var device = container.MobileDeviceTokenSet.FirstOrDefault(p => p.UserId == userId);
                      if(device != null)
                      {
                          deviceToken = device.Device_Token;
                      }
                  });

            return deviceToken;
        }

        public void ClearDeviceToken(Guid userId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                  container =>
                  {
                      var device = container.MobileDeviceTokenSet.FirstOrDefault(p => p.UserId == userId);
                      if (device != null)
                      {
                          container.MobileDeviceTokenSet.DeleteObject(device);
                      }
                  });

        }
    }
}